package debtbundler.domain.entity.impl;

import java.util.LinkedHashSet;
import java.util.logging.Level;
import java.util.logging.Logger;


/**
 * A base class for listenable entities. To avoid problems with non-serializable <code>EntityListener</code>s,
 * the listener collection of this class is transient. Therefore, after deserialization,
 * listeners must be added again
 * 
 * @author Anssi
 *
 */
abstract class AbstractListenableEntity extends AbstractEntity implements ListenableEntity {
	private static final long serialVersionUID = 1L;
	private static Logger logger = Logger.getLogger(AbstractListenableEntity.class.getName());
	
	protected transient LinkedHashSet<EntityListener> listeners = new LinkedHashSet<EntityListener>();


	@Override
	public synchronized boolean addEntityListener(EntityListener listener) {
		if (listener == this) {
			return false;
		}
		if (listeners == null) {
			 listeners = new LinkedHashSet<EntityListener>(); // instantiated on call instead of constructor because the field is transient
		}
		return this.listeners.add(listener);
	}

	@Override
	public synchronized boolean removeEntityListener(EntityListener listener) {
		return listeners != null ? this.listeners.remove(listener) : false;
	}
	
	/**
	 * Notifies all <code>EntityListener</code>s of this entity about an update in it.
	 * Also sets this entity's updatedDate and updatedBy.
	 */
	protected void fireEntityUpdateEvent() {
		markUpdated();
		if (listeners != null) { 
			for (EntityListener listener : listeners) {
				listener.modelStateChanged(this);
			}
		}
		logger.log(Level.FINER, "Entity {0} has fired update event", this);
	}	

}